package cn.agile4j.rpc.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;

import cn.agile4j.rpc.RpcClient;
import cn.agile4j.rpc.pojo.RpcRequest;
import cn.agile4j.rpc.pojo.RpcResponse;
import cn.agile4j.rpc.registry.ServiceDiscovery;

/**
 * 使用 Java 提供的动态代理技术实现 RPC 代理（当然也可以使用 CGLib 来实现）
 * 
 * @author Administrator
 */
public class RpcProxy {

	private String serverAddress ;
	private ServiceDiscovery serviceDiscovery ;
	
	public RpcProxy(String serverAddress) {
		this.serverAddress = serverAddress;
	}
	public RpcProxy(ServiceDiscovery serviceDiscovery) {
		this.serviceDiscovery = serviceDiscovery;
	}
	
	@SuppressWarnings("unchecked")
	public <T> T create(Class<?> interfaceClass) {
		return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), 
					new Class<?>[]{interfaceClass}, 
					new InvocationHandler() {
						@Override
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							RpcRequest request = new RpcRequest(); // 创建并初始化 RPC 请求
							request.setRequestId(UUID.randomUUID().toString());
							request.setClassName(method.getDeclaringClass().getName());
							request.setMethodName(method.getName());
							request.setParameterType(method.getParameterTypes());
							request.setPrameters(args);
							
							if (serviceDiscovery != null) {
								serverAddress = serviceDiscovery.discover(); // 发现服务
							}
							
							String[] array = serverAddress.split(":");
							String host = array[0] ;
							int port = Integer.valueOf(array[1]) ;
							
							RpcClient client = new RpcClient(host, port);	// 初始化 RPC 客户端
							RpcResponse response = client.send(request) ; // 通过 RPC 客户端发送 RPC 请求并获取 RPC 响应
							
							if (response.isError()) {
								throw response.getError();
							} else {
								return response.getResult() ;
							}
						}
					}
				);
	}

}
